#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 28 20:20:03 2025

@author: jack
"""
#%%
import matplotlib.font_manager as fm

# 获取系统中所有可用的字体
available_fonts = fm.findSystemFonts(fontpaths=None, fontext='ttf')

# 打印字体列表
for font in available_fonts:
    print(fm.FontProperties(fname=font).get_name())




#%%plot基础

from matplotlib import pyplot as plt

x = range(2,26,2)
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 27, 22, 18, 15]
# print(len(x))
# print(len(y))

plt.figure(figsize=(20,8), dpi=80) #设定图面大小

plt.plot(x,y)

plt.xticks(range(0, 25))  #通过list设定x,y轴的显示
plt.yticks(range(min(y),max(y)+1))

# plt.savefig('./t1.png') #可保存为png或svg


plt.show()

#%%

from matplotlib import pyplot as plt
import random

x = range(120)
y = [random.randint(20,35) for i in range(120)]

plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y,label='a')

xlabels = [f'10点{i}分' for i in range(60)]
xlabels += [f'11点{i}分' for i in range(60)]

plt.xticks(list(x)[::3], xlabels[::3], rotation=90) #x轴标签添加文字，list(x)[::3]标签的轴上位置，xlabels[::3]标签的内容，rotation=90旋转90度
                                                    #目前中文不显示


plt.grid(alpha=0.4) #增加网格
plt.legend(loc='upper left') #图例，需要plt.plot中添加label，loc表示位置
plt.show()

#%%多次条形图

from matplotlib import pyplot as plt

a = ['aa','ab','ac','ad']
b_16 = [15746,312, 4497, 319]
b_15 = [12357,156, 2045, 168]
b_14 = [2358,399,2358,362]


bar_width = 0.1
x_14 = range(len(a))
x_15 = [i+bar_width for i in x_14] #使x_15的条形图与x_14错开1个bar显示
x_16 = [i+2*bar_width for i in x_14]


plt.figure(figsize=(20,8),dpi=80)
plt.bar(x_14,b_14,width=bar_width,label='sep.14')
plt.bar(x_15,b_15,width=bar_width,label='sep.15')
plt.bar(x_16,b_16,width=bar_width,label='sep.16')

plt.xticks(x_15,a) #将标签与x_15对齐，因为x_15居中

plt.legend()
plt.show()

#%%条形图

from matplotlib import pyplot as plt

a = ['aa','ab','ac','ad','ae','af','ag','ah','ai','aj','ak','al','am','an','ao']
b = [56.01,26.94, 17.53,16.49,15.45,12.96,11.8, 11.61, 11.28, 11.12,10.49, 10.3,8.75, 7.55,7.32]
# print(len(b))
# print(len(a))

plt.figure(figsize=(20,8),dpi=80)
# plt.bar(range(len(a)),b,width=0.9) #bar绘制条形图，竖的条形图，width是条形宽度
plt.barh(range(len(a)),b,height=0.9, color='r') #barh绘制条形图，横的条形图，height是条形宽度
plt.show()

#%%直方图

#直方图用来统计每个量在各组中出现的频率

from matplotlib import pyplot as plt

a=[131,98, 125,131,124,139,131,117,128,108,135,138,131,102,107,114,119,128,121]

d = 5 #组距，每组的跨度
num_bins = (max(a)-min(a))//d #组数，//除以 以后向下取整

plt.hist(a,num_bins+1)
# plt.hist(a,5) #将数据自动分成5组
plt.xticks(range(min(a),max(a)+d,d)) #将刻度与直方图对齐，但图上后面还会错开一点，如何不错开呢？
plt.grid()

plt.show()

#%%

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(8,4),dpi=80)
plt.subplot(2,3,1)
plt.subplot(2,3,2)
plt.subplot(2,3,3)
plt.subplot(2,3,4)
plt.subplot(2,3,5)
plt.subplot(2,3,6)
plt.show()

#%%

x = np.linspace(-np.pi, np.pi, 256) # 弧度-pi到pi，取256个
c,s = np.cos(x), np.sin(x)

plt.plot(x, c)
plt.plot(x, s)
plt.show()

#%%

plt.figure(figsize=(8,4),dpi=80) #图像大小，长8*高6英寸，dpi 80，如何使用毫米？
plt.subplot(1,1,1) # 第1幅图，图面1*1
x = np.linspace(-np.pi, np.pi, 256)
c,s = np.cos(x), np.sin(x)
plt.plot(x, c, color='b', linewidth=1.0, linestyle='-', label='cosine') # r=red, b=blue, y=yellow, k=black, g=green
plt.plot(x, s, color='g', linewidth=1.0, linestyle='-', label='sine')
plt.xlim(x.min()*1.1, x.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi], 
           [r'$-\pi$',r'$-\frac{\pi}{2}$', 0, r'$\frac{\pi}{2}$', r'$\pi$', ]) 
plt.ylim(c.min()*1.1, c.max()*1.1)
plt.yticks([-1, 0, 1]) 

# 通过移动，隐藏图中4个轴的位置，来改变图形显示
ax = plt.gca() # gca = get current axis, 将命令简化
ax.spines['right'].set_color('none') # 让轴不显示
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data', 0)) #将轴的位置移动到数据0处
ax.spines['left'].set_position(('data', 1))
ax.xaxis.set_ticks_position('bottom') # 轴标签的位置
ax.yaxis.set_ticks_position('left')

#增加legend标示
# plt.plot(x, c, color='b', linewidth=2.5, linestyle='-', label='cosine') #只要增加label项，就会显示在legend

# plt.plot(x, s, color='r', linewidth=2.5, linestyle='-', label='sine')
# plt.legend(loc='upper left')

plt.show()

#%%

plt.figure(figsize=(8,4),dpi=80) #图像大小，长8*高6英寸，dpi 80，如何使用毫米？
plt.subplot(1,1,1) # 第1幅图，图面1*1
x = np.linspace(-np.pi, np.pi, 256)
c,s = np.cos(x), np.sin(x)
plt.plot(x, c, color='b', linewidth=1.0, linestyle='-', label='cosine') # r=red, b=blue, y=yellow, k=black, g=green
plt.plot(x, s, color='g', linewidth=1.0, linestyle='-', label='sine')
plt.xlim(x.min()*1.1, x.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi], 
           [r'$-\pi$',r'$-\frac{\pi}{2}$', 0, r'$\frac{\pi}{2}$', r'$\pi$', ]) 
plt.ylim(c.min()*1.1, c.max()*1.1)
plt.yticks([-1, 0, 1]) 

# 通过移动，隐藏图中4个轴的位置，来改变图形显示
ax = plt.gca() # gca = get current axis, 将命令简化
ax.spines['right'].set_color('none') # 让轴不显示
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data', 0)) #将轴的位置移动到数据0处
ax.spines['left'].set_position(('data', 0))
ax.xaxis.set_ticks_position('bottom') # 轴标签的位置
ax.yaxis.set_ticks_position('left')

#增加legend标示
# plt.plot(x, c, color='b', linewidth=2.5, linestyle='-', label='cosine') #只要增加label项，就会显示在legend

# plt.plot(x, s, color='r', linewidth=2.5, linestyle='-', label='sine')
plt.legend(loc='upper left')

t = (2/3)*np.pi
plt.plot([t,t], [0,np.cos(t)], color = 'b', linewidth=2.5, linestyle='--') # 显示竖直虚线
plt.scatter([t], [np.cos(t)], 100, color = 'r') #显示大圆点
plt.annotate(r'$cos \frac{2\pi}{3} = -\frac{1}{2}$', #这里\frac后面必须有大括号，即使1个数，与obsidian不同
            xy=(t, np.cos(t)), xycoords='data', xytext=(-90,-50),
            textcoords = 'offset points', fontsize = 16,
            arrowprops = dict(arrowstyle='->', connectionstyle ='arc3,rad=.2'))

for label in ax.get_xticklabels()+ax.get_yticklabels():
    label.set_fontsize(20)  #设置字体大小
    label.set_bbox(dict(facecolor='white', edgecolor='None',alpha=0.65)) #不知道干什么？


plt.show()


#%%

# 饼图

n = 20
z = np.ones(n)
z[-1] *= 2

# plt.axes([0.025, 0.025, 0.95, 0.95]) # 怎么排列绘图，看不懂
                                       #没有这行好像没区别

plt.pie(z,explode=z*.05, colors=[f'{i/float(n)}' for i in range(n)]) # 饼图使用plt.pie，参数看不懂
plt.axis('equal')
plt.xticks([])
plt.yticks()

plt.show()

#%%


# matplotlib.use('Agg') #有这行反而出不来图
fig = plt.figure(figsize=(5,4),dpi=72)
# axes = fig.add_axes([.01,.01,.98,.98]) #加了这句，轴上没有标签
x = np.linspace(0,2,200)
y = np.sin(2*np.pi*x)
plt.plot(x,y,lw=2) #lw=linewidth
plt.ylim(-1.1,1.1)
plt.grid()

plt.show()

#%%
#点图
n = 1024
x = np.random.normal(0,1,n)
y = np.random.normal(0,1,n)
t = np.arctan2(y,x)
plt.axes([.025, .025, .95, .95]) #控制图的大小，具体不懂
# plt.scatter(x,y,s=75,c=t,alpha=.5)
plt.scatter(x,y,s=75,c=t,alpha=.5) #c=t指的是色表

plt.xlim(-1.5,1.5)
plt.xticks([])
plt.ylim(-1.5,1.5)
plt.yticks([])

plt.show()

#%%
fig = plt.figure()
fig.subplots_adjust(bottom=.025, left=.025, top=.975, right=.975)

plt.subplot(2,1,1) #plt.subplot(2,1,1)，(行，列，序号)
plt.xticks([])
plt.yticks([])

plt.subplot(2,3,4)
plt.xticks([])
plt.yticks([])

plt.subplot(2,3,5)
plt.xticks([])
plt.yticks([])

plt.subplot(2,3,6)
plt.xticks([])
plt.yticks([])

#%%

import matplotlib
# matplotlib.use('Agg') #有这行反而出不来图
fig = plt.figure(figsize=(5,4),dpi=72)
# axes = fig.add_axes([.01,.01,.98,.98]) #加了这句，轴上没有标签
x = np.linspace(0,2,200)
y = np.sin(2*np.pi*x)
plt.plot(x,y,lw=2, c='r') #lw=linewidth, c=color
# plt.ylim(-1.1,1.1)
plt.xticks(np.arange(0,2,0.1))
plt.yticks(np.arange(-1,1,0.1))
plt.grid()

plt.show()


#%%

plt.axes([.1,.1,.8,.8]) #大框
plt.xticks([])
plt.yticks([])
plt.text(.6,.6,'axes([.1,.1,.8,.8])', ha='center', va='center', size=16, alpha=.5)
#.6,.6,是位置，ha水平对齐，va竖直对齐

plt.axes([.2,.2,.3,.3]) #小框
plt.xticks([])
plt.yticks([])
plt.text(.8,.6,'axes([.2,.2,.3,.3])', ha='center', va='center', size=16, alpha=.5)

plt.show()

#%%

plt.figure(figsize=(6,4))
plt.subplot(2,1,1)
plt.xticks([]) #不写这个，就会有标注
plt.yticks([])
plt.text(.5,.5,'subplot(2,1,1)', ha='center', va='center', size=16, alpha=.5)

plt.subplot(2,1,2)
plt.xticks([])
plt.yticks([])
plt.text(.5,.5,'subplot(2,1,2)', ha='center', va='center', size=16, alpha=.5)

# plt.tight_layout() #边框紧靠图边沿
plt.show()

#%%
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure() #指定缩写
ax = Axes3D(fig)
x = np.arange(-4, 4, .25)
y = np.arange(-4, 4, .25)
x,y = np.meshgrid(x,y)
r = np.sqrt(x**2+y**2)
z = np.sin(r)

ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=plt.cm.hot)
ax.contourf(x, y, z, zdir='z', offset=-1, cmap=plt.cm.hot) #两幅图函数不一样，有什么区别
ax.set_zlim(-2, 2)
plt.show()

#%%

#2维色块图
def f(x, y):
    return (1 - x / 2 + x**5 + y**3)*np.exp(-x**2 - y**2)

n = 10
x = np.linspace(-3, 3, int(3.5 * n)) # 需转为int，否则报错
y = np.linspace(-3, 3, int(3.0 * n))
x1, y1 = np.meshgrid(x, y)
z = f(x1, y1)

plt.axes([.025, .025, .95, .95])
plt.imshow(z, interpolation='nearest', cmap='bone', origin='lower')
plt.colorbar(shrink=.9) #控制colorbar的高度
plt.xticks([])
plt.yticks([])
plt.show()

#%%

#箭头图，形状与颜色都不同？
n = 8
x, y = np.mgrid[0:n, 0:n] #待学习？
t = np.arctan2(y - n / 2., x - n / 2.)
r = 10 + np.sqrt((y - n / 2.)**2 + (x - n / 2.)**2)
u,v = r * np.cos(t), r * np.sin(t)

plt.axes([.025, .025, .95, .95])
plt.quiver(x, y, u, r, alpha=.5)
plt.quiver(x, y, u, r, edgecolor='k', facecolor='None', linewidth=.5)

plt.xlim(-1, n)
plt.xticks([])
plt.ylim(-1, n)
plt.yticks([])

plt.show()

#%%
#极坐标色块图,大部分看不懂
ax = plt.axes([.025, .025, .95, .95], polar=True) #polar=True 极坐标
n = 20
theta = np.arange(0., 2*np.pi, 2*np.pi/n)
radii = 10 * np.random.rand(n)
width = np.pi / 4 * np.random.rand(n)
bars = plt.bar(theta, radii, width=width, bottom=0.)

for r,bar in zip(radii, bars):
    bar.set_facecolor(plt.cm.jet(r/10.))
    bar.set_alpha(.5)
    
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.show()

#%%
#等高线图
def f(x, y):
    return (1 - x / 2 + x**5 + y**3)*np.exp(-x**2 - y**2)

n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
x1, y1 = np.meshgrid(x, y)

plt.axes([.025, .025, .95, .95])
plt.contourf(x1, y1, f(x1, y1), 8, alpha=.75, cmap=plt.cm.hot)
c = plt.contour(x1, y1, f(x1, y1), 8, colors='k', linewidth=.5) #提示没有linewidth参数？
plt.clabel(c, inline=1, fontsize=10)

plt.xticks([])
plt.yticks([])
plt.show()